home *** CD-ROM | disk | FTP | other *** search
- /* Evaluator.m:
- * You may freely copy, distribute, and reuse the code in this example.
- * NeXT disclaims any warranty of any kind, expressed or implied, as to its
- * fitness for any particular use.
- *
- *
- *
- */
-
- #import <foundation/NSString.h>
- #import <foundation/NSUtilities.h>
-
- #import "ScrollViewExtras.h"
- #import "Evaluator.h"
- #import "EOFDelegateAdaptorCategory.h"
-
-
- #define FAILURE NXLocalizedString("Failure:", NULL, \
- "Message given to user when an operation has failed.")
-
- #define CANNOT_CONNECT NXLocalizedString("Cannot connect to database", NULL, \
- "Message given to user to explain what fails. ")
-
- #define OK NXLocalizedString("OK", NULL, "Okay to continue ")
-
- @implementation Evaluator
-
- - initWithModelFile:(NSString *)filePath
- {
- char path[MAXPATHLEN];
- BOOL result=NO;
-
- [super init];
-
- // open the model file and connect to the database
- model = [[[EOModel alloc]
- initWithContentsOfFile: filePath] autorelease];
-
- if (!model)
- return nil;
-
-
- adaptor = [EOAdaptor adaptorWithModel:model];
- if (!adaptor)
- return nil;
-
- context = [adaptor createAdaptorContext];
- if (!context)
- return nil;
-
-
- channel = [context createAdaptorChannel];
-
- if (!channel)
- return nil;
-
- if (![channel isOpen])
- result = [channel openChannel];
- if (result)
- [resultsView sprintf:"Connection successful\n"];
- else
- [resultsView sprintf:"Connection failed\n"];
-
- [[NXBundle mainBundle] getPath:path forResource:"SQLWindow" ofType:"nib"];
- [NXApp loadNibFile:path owner:self withNames:NO];
- [(Window *)[resultsView window] setDelegate:self];
- [[resultsView window] setTitleAsFilename:[filePath cString]];
- [[queryView docView] selectAll:self];
- [[resultsView window] makeKeyAndOrderFront:self];
-
- /*----------------------------------------------------------------------
- * set up the channel delegate to SybaseDelegate for Sybase model files
- * use EOFDelegateCategory for Oracle model files
- *--------------------------------------------------------------------*/
-
- if ([[adaptor name] isEqualToString:@"Sybase"]) {
- sybaseDelegate = [[SybaseDelegate alloc] init];
- [channel setDelegate:sybaseDelegate];
- }
- else {
- sybaseDelegate = nil;
- [channel setDelegate:[[EOFDelegateAdaptorCategory alloc] init]];
- }
-
- return self;
- }
-
- - free
- {
- [model release];
- [adaptor release];
- [context release];
- [channel release];
- if (sybaseDelegate)
- [sybaseDelegate release];
-
- return [super free];
- }
-
- - evaluate:sender
- {
- BOOL result = NO;
- int charCount;
- char *buffer = NULL;
- NSDictionary *row;
-
- /*----------------------------------------------------------------------
- * get the SQL statement
- *--------------------------------------------------------------------*/
-
- if ((charCount = [[queryView docView] textLength]) > 0) {
- buffer = malloc((charCount+1) * sizeof(char));
- [[queryView docView] getSubstring:buffer start:0 length:charCount];
- buffer[charCount] = 0;
- while (charCount > 0 && buffer[--charCount] == '\n')
- buffer[charCount] = 0;
- [resultsView sprintf:"%s\n", buffer];
-
- }
- else {
- [resultsView sprintf:"Can't execute an empty string!\n"];
- return self;
- }
-
- /*----------------------------------------------------------------------
- * evaluate the SQL statement
- *--------------------------------------------------------------------*/
-
- [context beginTransaction];
- result = [channel evaluateExpression:
- [[NSString alloc] initWithCString:(const char *)buffer]];
-
- if (result){
- [resultsView sprintf:"SQL successfully evaluated\n"];
-
- while ([channel isFetchInProgress] == YES) {
- // get the array of attributes from the result set
- attributes = [channel describeResults];
-
- // since the EO Framework attributes are stored as Attribute1,
- // Attribute2, etc., build a dictionary to do conversion.
-
- [self buildColumnNamesDictionary:attributes];
-
- // The NSDictionary contains all the data for one row
- while ((row = [channel fetchAttributes: attributes withZone:
- [adaptor zone]]) != nil)
- // read data back
- [self readDataFromDict:row ];
-
- }
- [context commitTransaction];
-
- }
- else {
- // do clean-up if SQL statement cannot be evaluated.
- [resultsView sprintf:"SQL evaluation failed\n"];
- if ([channel isFetchInProgress] == YES)
- [channel cancelFetch];
- [context rollbackTransaction];
- }
- free(buffer);
- return self;
- }
-
-
-
- /* Build a dictionary where the Keys are Attribute1, Attribute2, etc.,
- * while the values are the actual column names as specified in the
- * database.
- */
- - buildColumnNamesDictionary:(NSArray *) attributesArray
- {
- NSEnumerator *enumerator;
- EOAttribute *attribute;
- NSMutableArray *keys = [NSMutableArray array];
- NSMutableArray *values = [NSMutableArray array];
-
- enumerator = [attributesArray objectEnumerator];
-
- while ((attribute = [enumerator nextObject]) != nil) {
- [keys addObject:[attribute name]];
- [values addObject:[attribute columnName]];
- }
- columnNamesDict = [NSDictionary dictionaryWithObjects:values
- forKeys: keys];
- return self;
- }
-
- /* Cycle through the key and value pairs of the dictionary
- * and print them to result view
- *
- */
- - readDataFromDict:(NSDictionary *) dictionary
- {
- NSEnumerator *keyEnumerator;
- NSString * key;
- NSString * newKey;
- id value;
- char buffer[1024];
- SybaseRowType rowType=0;
-
- keyEnumerator = [dictionary keyEnumerator];
- if (sybaseDelegate)
- rowType = [sybaseDelegate currentRowType];
-
- //print the full dictionary for Sybase regular rows or if the Oracle adaptor is used
- if ( ((sybaseDelegate) && (rowType == SybaseRegularRow ))
- || (sybaseDelegate == nil) )
- {
- while ((key = [keyEnumerator nextObject]) != nil) {
- newKey = [columnNamesDict objectForKey:[key description]];
-
- value = [dictionary objectForKey:key];
- sprintf(buffer, "%s: \t %s\n", [[newKey description] cString],
- [[(NSObject *)value description] cString]);
- [resultsView sprintf:buffer];
- }
- }
- else {
- // This must be one special sybase row
- switch (rowType) {
- case SybaseComputeRow:
- case SybaseReturnStatusRow:
- // print one row of data only
- key = [keyEnumerator nextObject];
- value = [dictionary objectForKey:key];
- sprintf(buffer, "Row type: %s \t %s\n", (rowType == SybaseComputeRow) ?
- "SybaseComputeRow": "SybaseReturnStatusRow",
- [[(NSObject *)value description] cString]);
- [resultsView sprintf:buffer];
- sprintf(buffer, "************************************\n");
- [resultsView sprintf:buffer];
- break;
- case SybaseReturnParameterRow:
- // Exercise for the reader: How to format this row
- [resultsView sprintf:"SybaseReturnParameterRow: No data printed\n"];
- break;
- case SybaseRegularRow:
- default:
- break;
- }
- }
-
-
- return self;
- }
-
- - clear:sender
- {
- [resultsView clear:sender];
- [[queryView docView] selectText:self];
- return self;
- }
-
- - close:sender
- {
- // close the adaptor channel and disconnect from the database
- [channel closeChannel];
- // close the main window
- [[NXApp mainWindow] performClose:sender];
- return self;
- }
-
-
-
- /*--------------------------------------------------------------------------
- * Announcing Trace Info
- *------------------------------------------------------------------------*/
- - (void) logString:(NSString *) aString
- {
- [resultsView sprintf: "%s", [aString cString]];
- }
-
- - (void) announce:sender selector:(SEL)selector
- {
- return [self announce:sender selector:selector with:nil];
- }
-
-
- - (void) announce:sender selector:(SEL)selector with:array
- {
- NSMutableString *string;
-
- string = [NSMutableString stringWithFormat:@"BEGIN> {Sender = %s%s",
- [[(NSObject *)[sender class] description] cString], "}" ];
-
-
- [string appendFormat:@" \n\t{Delegate Method = %s} ", sel_getName(selector)];
-
- if (array)
- {
- id object;
- id verboseString = [NSMutableString stringWithCapacity:0];
- id enumerator = [array objectEnumerator];
-
- while ((object = [enumerator nextObject]) != nil)
- [verboseString
- appendFormat:@"\n\t{Argument = %s} \n\t{Argument Description = %s} ",
- [[(NSObject *)[object class] description] cString],
- [[(NSObject *) object description] cString]];
-
- [string appendString:verboseString];
- }
-
-
- [string appendFormat:@"\n"];
- [resultsView sprintf: "%s", [string cString]];
- }
-
-
- /* Window Delegate method -- constrain window resizing */
-
- - windowWillResize:sender toSize:(NXSize *)frameSize
- {
- if ( frameSize->height < 230 ) frameSize->height= 230;
- return self;
- }
-
-
- @end
-